#!/usr/bin/python3
import sys
import re
from dataclasses import dataclass
import os

@dataclass(frozen=True)
class Pos:
    x: int
    y: int

    def walk(self, dpos, steps):
        return Pos(self.x + dpos.x * steps, self.y + dpos.y * steps)
    
    def add_x(self, x):
        return Pos(self.x + x, self.y)

    def add_y(self, y):
        return Pos(self.x, self.y + y)

    def minimize(self, pos):
        return Pos(min(self.x, pos.x), min(self.y, pos.y))

    def maximize(self, pos):
        return Pos(max(self.x, pos.x), max(self.y, pos.y))


def grid_str(points, upperleft, lowerright):
    chars = [['#' if Pos(x, y) in points else ' ' for x in range(upperleft.x, lowerright.x + 1)] for y in range(upperleft.y, lowerright.y + 1)]
    return '\n'.join([''.join(line) for line in chars])

def generate_directions(pos):
    yield pos.add_x(-1)
    yield pos.add_x(1)
    yield pos.add_y(-1)
    yield pos.add_y(1)

def flood(boundary, upperleft, lowerright):
    count = 0
    start = Pos((upperleft.x + lowerright.x) // 2, (upperleft.y + lowerright.y) // 2)
    last = set()
    seen = set([start])
    considered = boundary.copy()
    #n = 0
    while last != seen:
        last = seen.copy()
        for p in last:
            for np in generate_directions(p):
                if np in considered:
                    continue
                seen.add(np)
            considered.add(p)
            seen.remove(p)
        #n += 1
        #if n % 32 == 0:
            #n = 0
            #os.system('clear')
            #print(grid_str(considered, upperleft, lowerright))
    print(len(considered))

def part12(swapped=False):
    print('part 1')
    corners = set()
    boundary = set()
    pos = Pos(0, 0)
    upperleft = Pos(0, 0)
    lowerright = Pos(0, 0)
    directions = { 'U': Pos(0, -1) , 'R': Pos(1, 0), 'D': Pos(0, 1), 'L': Pos(-1, 0) }
    for line in map(str.strip, sys.stdin):
        found = re.findall(r'([UDRL]) ([0-9]+) \(#([0-9a-f]+)\)', line)[0]
        if swapped:
            direction = {'0': 'R', '1': 'D', '2': 'L', '3': 'U'}[found[2][-1]]
            steps = int(found[2][:-1], 16)
        else:
            direction, steps = found[0], int(found[1])
        print(direction, steps)
        last = pos
        pos = pos.walk(directions[direction], steps)
        upperleft = upperleft.minimize(pos)
        lowerright = lowerright.maximize(pos)
        for x in range(min(last.x, pos.x), max(last.x, pos.x) + 1):
            for y in range(min(last.y, pos.y), max(last.y, pos.y) + 1):
                boundary.add(Pos(x, y))
        corners.add(pos)
    print(grid_str(boundary, upperleft, lowerright))
    flood(boundary, upperleft, lowerright)

if sys.argv[1] in '1':
    part12()
else:
    part12(swapped=True)
